package com.jian.socks5.common;

import com.jian.socks5.tcp.handler.Client2ServerHandler;
import com.jian.socks5.tcp.handler.Server2ClientHandler;
import com.jian.socks5.udp.codec.Socks5UDPResponseEncoder;
import com.jian.socks5.udp.handler.Socks5UDPHandler;
import com.jian.socks5.udp.handler.UDPDatagramHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.EventExecutorGroup;

import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

public class Constants {

    public static Socks5AddressType localUdpAddrType = Socks5AddressType.DOMAIN;

    public static String localUdpAddr = "192.168.137.1";

    public static int localUdpPort = 8889;

    /***
     * udp代理服务是否已启动
     */
    public static AtomicBoolean udpServerIsStart = new AtomicBoolean(false);

    /***
     * 绑定在客户端连接Channel上的目标机器channel属性
     */
    public static AttributeKey<Channel> CLIENT_CHANNEL_ATTR = AttributeKey.valueOf("DEST_CHANNEL");

    /***
     * 绑定在目标机器Channel上的客户端连接channel属性
     */
    public static AttributeKey<ChannelHandlerContext> DEST_CHANNEL_ATTR = AttributeKey.valueOf("CLIENT_CHANNEL");

    /***
     * Channel上的IP属性
     */
    public static AttributeKey<String> CHANNEL_ATTR_IPINFO = AttributeKey.valueOf("IP_PORT");

    /***
     * 客户端数据转发到目标机handler
     */
    public static Client2ServerHandler client2ServerHandler = new Client2ServerHandler();

    /***
     * 目标机数据转发到客户机handler
     */
    public static Server2ClientHandler server2ClientHandler = new Server2ClientHandler();

    //public static Socks5UDPRequestDecoder socks5UDPRequestDecoder = new Socks5UDPRequestDecoder();
    /***
     * socks5 udp响应解码器
     */
    public static Socks5UDPResponseEncoder socks5UDPResponseEncoder = new Socks5UDPResponseEncoder();

    /***
     * udp响应处理
     */
    public static UDPDatagramHandler udpDatagramHandler = new UDPDatagramHandler();

    /***
     * socks UDP响应处理
     */
    public static Socks5UDPHandler socks5UDPHandler = new Socks5UDPHandler();



    /***
     * 本地连接目标机器工作线程组
     */
    public static EventLoopGroup eventExecutors = new NioEventLoopGroup(5);

    /***
     * UDP连接工作线程组
     */
    public static EventLoopGroup udp_eventExecutors = new NioEventLoopGroup(5);

    /***
     * 服务端接受连接处理线程组
     */
    public static EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup(1);

    /***
     * UDP连接线程组
     */
    public static EventLoopGroup udpBossEventLoopGroup = new NioEventLoopGroup(1);

    /***
     * 服务端编解码工作线程组
     */
    public static EventLoopGroup workEventLoopGroup = new NioEventLoopGroup(2);

    /****
     * 具体工作线程
     */
    public static EventExecutorGroup defaultEventLoopGroup = new DefaultEventLoopGroup(5);

    /***
     * udp 接收来自服务端UDP数据的客户端IP和端口信息
     */
    public static AttributeKey<InetSocketAddress> udpClientSenderAddrAttr = AttributeKey.valueOf("UDPClientSenderIP");

    /***
     *  udp 接收来自客户端地址类型
     */
    public static AttributeKey<Socks5AddressType> udpClientSenderAddrTypeAttr = AttributeKey.valueOf("UDPClientAdrType");

    /***
     * 目标机器转发至客户ctx
     */
    public static AttributeKey<ChannelHandlerContext> udpClientSenderChannelAttr = AttributeKey.valueOf("UDPClientChannelIP");


    /***
     * 客户端能接受来自该IP和端口的服务端的数据包
     */
    public static Set<String> ipAndPorts = new HashSet<>();

    /***
     * 客户端发送数据的IP端口及目标IP端口一致对应的channel，提高channel复用
     */
    public static Map<String, Channel> dstIPAndPortEqSenderIPPort = new ConcurrentHashMap<>();

}
